home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / serial / zyxel-1.5-s / zyxel-1 / zplay / zplay.c < prev   
C/C++ Source or Header  |  1994-10-06  |  7KB  |  278 lines

  1. /*
  2.     zplay, play Zyxel zad files.
  3.  
  4.    Autor:    Michael Beck - beck@informatik.hu-berlin.de
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <malloc.h>
  9. #include <unistd.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #ifndef __STDC__
  13. #include <getopt.h>
  14. #endif /* __STDC__ */
  15. #include <fcntl.h>
  16.  
  17. #include "dsp.h"
  18.  
  19. /* global data */
  20. char * command;
  21.  
  22. /* Local prototypes */
  23. int play (int audio, char * fname );
  24. int readzad(int voice, FILE * ifile);
  25. void ToVoc(int audio,int Vdata);
  26. void Adaptive(char DataBit);
  27.  
  28.  
  29. /* And here we are */
  30.  
  31. int main (int argc, char *argv[]) {
  32.     char c;
  33.     int openct=100,audio,volume,dspspeed=DEFAULT_DSP_SPEED,samplesize=8,abuf;
  34.  
  35.     /* Save the program name for use in error messages */
  36.     command = argv[0];
  37.  
  38.     while ((c = getopt (argc, argv, "qs:b:v:")) != EOF)
  39.         switch (c) {
  40.         case 's':
  41.             dspspeed = atoi (optarg);
  42.                 if (dspspeed < 300)
  43.                     dspspeed *= 1000;
  44.             break;
  45.  
  46.         case 'b':
  47.             samplesize = atoi (optarg);
  48.             break;
  49.  
  50.         case 'q':
  51.             verbose=!verbose;
  52.             break;
  53.  
  54.         case 'v':
  55.             volume = atoi (optarg);
  56.             break;
  57.         default:
  58.             fprintf (stderr, "Usage: %s [-s Hz] [-b 8|12|16] <filename>\n", argv[0]);
  59.             exit (-1);
  60.     }
  61.  
  62.   /* We will loop <openct> times, with 1 sec delay */
  63.   while(openct--) {
  64.       if((audio = open (AUDIO, O_WRONLY, 0))!=-1)
  65.         break;
  66.  
  67.     if(errno!=EBUSY) {
  68.             perror (AUDIO);
  69.             exit (-1);
  70.     }
  71.     if(verbose)
  72.         printf("[%4d] waiting\n",getpid());
  73.     sleep(1);
  74.   }
  75.  
  76.   if(verbose)
  77.     printf("[%4d] start\n",getpid());
  78.  
  79.  
  80.     /* Allocate buffers for memory */
  81.     dsp_init(audio);
  82.  
  83.     /* Sync the DSP */ 
  84.     sync_dsp(audio);
  85.  
  86.      /* sync_dsp(audio); */
  87.     set_dsp_speed(audio,dspspeed);
  88.     set_dsp_samplesize(audio,samplesize);
  89.  
  90.     /* Play the file */
  91.     play(audio,argv[optind++]);
  92.  
  93.      close_dsp(audio);
  94.     if(verbose)
  95.         printf("[%4d] done\n",getpid());
  96.     return 0;
  97. }
  98.  
  99. /* copy the file until EOF */
  100. int play (int audio, char * fname ) {
  101.     FILE * ifile;
  102.  
  103.     /* Open the source file */
  104.     if((ifile=fopen(fname,"rb"))==NULL) {
  105.         fprintf(stderr,"%s unable to open input\n", command);
  106.         perror(fname);
  107.         return -1;
  108.     }
  109.  
  110.     /* Play zad file  */
  111.     readzad(audio,ifile);
  112.  
  113.     fclose(ifile);
  114. }
  115.  
  116.  
  117. /* Conversion variables */
  118. char CompBit;
  119. long EstMax,Delta,Data,Pack;
  120. int    MaxTbl1[] = { 0x3800, 0x5600 } ;
  121. int     MaxTbl2[] = { 0x399A, 0x3A9F, 0x4D14, 0x6607 } ;
  122. int    MaxTbl3[] = { 0x3556, 0x3556, 0x399A, 0x3A9F,
  123.                       0x4200, 0x4D14, 0x6607, 0x6607 } ;
  124. int  *MaxTbl = MaxTbl2;
  125.  
  126. /* -------------------------------- */
  127. /*  ZyXEL ADPCM -> .VOC conversion  */
  128. /* -------------------------------- */
  129. int readzad(int audio, FILE * ifile) {
  130.  
  131.     char ZheadBuf0[16] ;
  132.     char ZheadBuf1[16] = { 'Z','y','X','E','L',2,0,0,0,0,0,0,0,0,0,0 } ;
  133.  
  134.     /* Read from source file */
  135.     if( fread(ZheadBuf0,sizeof(char),16,ifile)!=16) {
  136.         fprintf(stderr,"%s zad file without header\n", command);
  137.         perror(command);
  138.         return -1;
  139.     }
  140.  
  141.  
  142.     /* compare with the expected header */
  143.     if ( strncmp( ZheadBuf0, ZheadBuf1, 6)) {
  144.         fprintf(stderr,"%s incorrect zad file\n", command);
  145.         perror(command);
  146.         return -1;
  147.     }
  148.  
  149.     /* Parameters */
  150.     Delta=5;
  151.     EstMax=0;
  152.  
  153.     /* Change from 2-bit to 3-bit ADPCM */
  154.     CompBit = ZheadBuf0[10] ;
  155.     switch ( CompBit )
  156.     {
  157.     case 1:
  158.         MaxTbl = MaxTbl1;
  159.         if(verbose)
  160.             printf("2-bit ADPCM\n");
  161.         break;
  162.     case 2:
  163.         MaxTbl = MaxTbl2;
  164.         if (verbose)
  165.             printf("3-bit ADPCM\n");
  166.         break;
  167.     case 3:
  168.         MaxTbl = MaxTbl3;
  169.         Delta=4;
  170.         if (verbose)
  171.             printf("4-bit ADPCM\n");
  172.         break;
  173.     }
  174.  
  175.     while ((Data=getc(ifile)) != EOF )    {
  176.         switch ( CompBit )
  177.         {
  178.         case 1:
  179.             ToVoc(audio,(Data&0xc0)>>6) ; /* XX-- ---- */
  180.                         ToVoc(audio,(Data&0x30)>>4) ; /* --XX ---- */
  181.                         ToVoc(audio,(Data&0x0c)>>2) ; /* ---- XX-- */
  182.                         ToVoc(audio,Data&0x03) ;      /* ---- --XX */
  183.                         break;
  184.         case 2:
  185.                         ToVoc(audio,(Data&0xe0)>>5) ; /* XXX- ---- */
  186.                         ToVoc(audio,(Data&0x1c)>>2) ; /* ---X XX-- */
  187.                         Pack = (Data&0x03)<<1 ;
  188.             Data = getc(ifile);
  189.                         ToVoc(audio,Pack|((Data&0x80)>>7)) ;
  190.                         ToVoc(audio,(Data&0x70)>>4) ; /* -XXX ---- */
  191.                         ToVoc(audio,(Data&0x0e)>>1) ; /* ---- XXX- */
  192.                         Pack = (Data&0x01)<<2 ;
  193.             Data = getc(ifile);
  194.                         ToVoc(audio,Pack|((Data&0xc0)>>6)) ;
  195.                         ToVoc(audio,(Data&0x38)>>3) ; /* --XX X--- */
  196.                         ToVoc(audio,Data&0x07) ;      /* ---- -XXX */
  197.                         break;
  198.         case 3:
  199.             ToVoc(audio,(Data&0xf0)>>4) ; /* XXXX ---- */
  200.                         ToVoc(audio,Data&0x0f) ;      /* ---- XXXX */
  201.                         break;
  202.                 }
  203.     }
  204. }
  205.  
  206. /**************************************************************************
  207.         ToVoc()
  208.  
  209.  
  210.  
  211.  Copyright 1992, ZyXEL Communications Corporation
  212.  ************************************************************************/
  213. void ToVoc(int audio, int Vdata)
  214. {
  215. int     Wdata ;
  216.         Adaptive((char)Vdata) ;
  217.         if ( EstMax > 8191 )
  218.                 Wdata = 8191 ;
  219.         else if ( EstMax < -8192 )
  220.                 Wdata = -8192 ;
  221.         else
  222.                 Wdata = EstMax ;
  223.     Wdata=((Wdata>>6)+128)&0xff;
  224.  
  225.     write_dsp_byte(audio,Wdata);
  226.  
  227.     /* write(audio,&Wdata,1); */
  228. }
  229.  
  230. /**************************************************************************
  231.         Adaptive(DataBit, SignBit)
  232.  
  233.  
  234.  
  235.  Copyright 1992, ZyXEL Communications Corporation
  236.  ************************************************************************/
  237. void Adaptive(char DataBit)
  238. {
  239. int     TmpMax ;
  240. char    TmpData, SignBit ;
  241. long    TmpDelta ;
  242. long    t0 ;
  243.  
  244. /******* This part is modified for the Firmware > 6.10 **************/
  245. /**/    t0 = (long)EstMax ;                                       /**/
  246. /**/    t0 *= 4093 ;                                              /**/
  247. /**/    t0 += 2048 ;                                              /**/
  248. /**/    t0 /= 4096 ;                                              /**/
  249. /**/    EstMax = (int)t0 ;                                        /**/
  250. /********************************************************************/
  251.  
  252.         SignBit = DataBit & (1<<CompBit) ;
  253.         DataBit &= ~(1<<CompBit) ;
  254.         if ( (Delta&1) && !SignBit )
  255.                 ++EstMax ;
  256.  
  257.         /* ------------------- */
  258.         /* Calculate the Delta */
  259.         /* ------------------- */
  260.         TmpDelta = Delta ;
  261.         TmpDelta *= MaxTbl[DataBit] ;
  262.         TmpDelta += 8192 ;
  263.         TmpDelta >>= 14 ;
  264.  
  265.         /* -------------------- */
  266.         /* Calculate the EstMax */
  267.         /* -------------------- */
  268.         TmpMax  = (Delta>>1) ;
  269.         while ( DataBit-- )
  270.                 TmpMax += Delta ;
  271.         if ( SignBit )
  272.                 EstMax -= TmpMax ;
  273.         else
  274.                 EstMax += TmpMax ;
  275.  
  276.         Delta = (int)TmpDelta ;
  277. }
  278.